/*
 * Layer.h
 *
 *  Created on: 04/01/2012
 *      Author: luiz
 */

#ifndef LAYER_H_
#define LAYER_H_

#include <string>
#include <vector>
#include <set>
#include "Cell.h"


class Layer {
private:

    // store matrix off cell
    Cell ***layer_grid;

    // number of horizontal cell's on grid
	int grid_size_x_;

	// number of vertical cell's on grid
	int grid_size_y_;

	std::vector<Cell*> cell_list_;

	int number_of_positions_used_per_cell_;

	//initialize and allocate properties
	void initialize();

	//deallocate and free all properties
	void deinitilize();


public:

	/*
	 * Constructor
	 */
	Layer(int grid_size_horizonta=0,int grid_size_vertica=0,int number_of_positions_used_per_cell=0);


	Layer(const Layer &layer);

	Layer& operator=(const Layer & layer);

	virtual ~Layer();


	/*
	 * Methods
	 */

	// create new cell at position on layer (grid) (x  and y axis)
	// @param int position x, int position y
	// @return Cell pointer to created cell - NULL if this cell wasn't created
	Cell* create_new_cell_at(int position_x,int position_y);

	void remove_cell_at(int position_x,int position_y);

	void remove_cell(Cell* cell);

	int number_of_cells() const;

	Cell* get_cell_at_list_index(int cell_index);

	Cell* get_cell_by_id(int id);

	Cell* get_cell_at_position(int pos_x, int pos_y);

	int number_of_cells_by_function(Cell::CELL_FUNCTION function);

	int number_of_positions_used_per_cell();

	void set_number_of_positions_used_per_cell(int number_of_positions_used_per_cell);

	int get_output_shift();

	bool verify_insertion(int pos_x, int pos_y);

	bool verify_conex();

	bool verify_conex_before_remove(Cell *cell);

	int grid_size_x() const;

	int grid_size_y() const;

	std::vector<Cell*> get_list_cells_by_function(Layer *layer,Cell::CELL_FUNCTION cell_function);

	std::vector<Cell*> cell_list();

	std::set<std::pair<int,int> > get_list_empty_places();

	std::vector<std::pair<int,int> > get_empty_neighborhood(Cell * cell, Layer * layer);

	Cell* get_lower_clock_zone_cell_neighborhood(Cell * cell, Layer * layer);

	int get_number_of_cells() const;

	// return string with layer information
	// @return string
	std::string print_layer();







};

#endif /* LAYER_H_ */
